﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RayDen.Library.Core;
using RayDen.Library.Core.Primitives;
using RayDen.RayEngine.Core.Library;
using RayDen.RayEngine.Core.Types;

namespace RayDen.RayEngine.Data
{
    public  class EnvironmentCamera : BaseCamera
    {
        float focal_scale = 120.0f;

        public new float Fov
        {
            get { return fieldOfView; }
            set { fieldOfView = value; }
        }

        public float fieldOfView = 45f, lensRadius = 0.9f;
        public float clipHither = 1e-4f, clipYon = 1e10f;
        Vector dir, x, y;
        private int Width;
        private int Height;
        private FastRandom rnd;

        private Transform world2Cam;
        private Point rayOrigin;

        public EnvironmentCamera(Point position, int w, int h)
        {
            var mat = new Matrix4x4().Translate(position.x, position.y, position.z);
            world2Cam = new Transform(ref mat);
            this.rayOrigin = position;
            Width = w;
            Height = h;
        }
        public override void GetRay(double x, double y, out Core.Types.RayData ray)
        {
            float theta = MathLab.M_PI * ((float)y/Height);
	        float phi = MathLab.M_2PI * ((float)x/Width);
            Vector dir = new Vector(MathLab.Sin(theta) * MathLab.Cos(phi), MathLab.Cos(theta),MathLab.Sin(theta) * MathLab.Sin(phi));
            ray = new RayData()
            {
                Org = rayOrigin,
                Dir = -(dir),
                minT = clipHither,
                maxT = clipYon
            };
        }

        public override void LookAt(Library.Core.Primitives.Point vector, Library.Core.Primitives.Point vector_2, Library.Core.Primitives.Vector vector_3)
        {
            var mat = new Matrix4x4().Translate(vector.x, vector.y, vector.z);
            world2Cam = new Transform(ref mat);
            this.rayOrigin = vector;
        }

        public override Library.Core.Primitives.Point UnProject(ref Library.Core.Primitives.Point v)
        {
            throw new NotImplementedException();
        }
    }
}
